﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Xml.Linq;

using ProjectBase.Core;

namespace ProjectBase.Tools.Publishing
{
    public abstract class PublishingHandlerBase : IPublishingHandler
    {
        #region members
        private int _priority = 100;
        #endregion members

        #region Init & Shutdown
        public abstract void Init(XElement settings);
        public virtual void Exit()
        {
            if (Successor.Is())
            {
                Successor.Exit();
            }
        }
        #endregion Init & Shutdown

        #region public IPublishingHandler
        public virtual PublishingResult Handle(object reporter, string message, Exception exception)
        {
            if (Publish(reporter, message, exception).Equals(PublishingResult.Finished))
            {
                return PublishingResult.Finished;
            }

            if (Successor.Is())
            {
                return Successor.Handle(reporter, message, exception);
            }
            return PublishingResult.Continue;
        }

        public virtual PublishingResult Handle(object reporter, Severity severity, object message, params object[] args)
        {
            if (Publish(reporter, severity, message, args).Equals(PublishingResult.Finished))
            {
                return PublishingResult.Finished;
            }

            if (Successor.Is())
            {
                return Successor.Handle(reporter, severity, message, args);
            }
            return PublishingResult.Continue;
        }

        public virtual PublishingResult Handle(object reporter, Func<string> message, Severity severity)
        {
            if (Publish(reporter, message, severity).Equals(PublishingResult.Finished))
            {
                return PublishingResult.Finished;
            }

            if (Successor.Is())
            {
                return Successor.Handle(reporter, message, severity);
            }
            return PublishingResult.Continue;
        }

        public virtual void SetSuccessor(IPublishingHandler successor)
        {
            Successor = successor;
        }
        #endregion public IPublishingHandler

        #region protected abstract
        protected abstract PublishingResult Publish(object reporter, string message, Exception exception);
        protected abstract PublishingResult Publish(object reporter, Severity severity, object message, params object[] args);
        protected abstract PublishingResult Publish(object reporter, Func<string> message, Severity severity);
        #endregion protected abstract

        #region properties

        public virtual int Priority
        {
            get { return _priority; }
            set { _priority = value; }
        }

        public virtual IPublishingHandler Successor { get; protected set; }
        #endregion properties
    }
}